﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Core.h".
//-------------------------------------------------------------------

#ifdef  COMPILER_MSVC

#ifndef _UXS_MSVC_COMPILER_H
#define _UXS_MSVC_COMPILER_H

#pragma once


// Version //

#define COMPILER_VERSION		_MSC_VER

//-------------------------------------------------------------------



// Export //

#define UX_DLL_EXPORT			__declspec( dllexport )
#define UX_DLL_IMPORT			__declspec( dllimport )
#define UX_DLL_PRIVATE			


//-------------------------------------------------------------------


// Warnings //

#pragma warning (push)

//#pragma warning (disable: 4201)		// nonstandard extension used : nameless struct/union
#pragma warning (disable: 4251)		// class '%class_name%' must have dll-interface...
#pragma warning (disable: 4996)		// this function or variable may be unsafe
//#pragma warning (disable: 4503)		// decorated name length exceeded, name was truncated

// for level 4
//#pragma warning (disable: 4481)		// nonstandard extension used
//#pragma warning (disable: 4127)		// conditional expression is constant
//#pragma warning (disable: 4201)		// nonstandard extension used : nameless struct/union
//#pragma warning (disable: 4512)		// assignment operator could not be generated
//#pragma warning (disable: 4480)		// nonstandard extension used: specifying underlying type for enum

#undef  _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS


#ifdef __UX_FAST__
//#	pragma warning (disable: 4552)
#	pragma warning (disable: 4553)
#endif	// __UX_FAST__

//-------------------------------------------------------------------



// Compiler Settings //

// function name as string
#define	UX_FUNCTION_NAME			__FUNCTION__

// set align of struct in bytes
#define	UX_ALIGN( _size )			__declspec( align( _size ) )

// returns align of type in bytes
#define UX_ALIGN_OF( _type )		__alignof( _type )

// always inline function
#define	UX_FORCE_INLINE				__forceinline

// never inline function
#define UX_NO_INLINE				__declspec (noinline)

// no code be generated for the arguments
// Warning: no analogs for other compilers!
#define	UX_NOOP						__noop

// value is always true
#define	UX_ASSUME( _cond )			__assume( _cond )

// don't use virtual table for struct/class
// Warning: no analogs for other compilers!
#define UX_NO_VTABLE				__declspec( novtable )

// function return unique pointer
#define	UX_RESTRICT					__declspec( restrict )

// function does not modify or reference visible global state and only modifies the memory
// pointed to directly by pointer parameters (first-level indirections). (MDSN)
// Warning: no analogs for other compilers!
#define	UX_NO_ALIAS					__declspec( noalias )

// type qualifier for pointer types
// another pointer cannot be used to access the data pointed to by the __restrict pointer. (MDSN)
// Warning: no analogs for other compilers!
#define	UX_RESTRICT_PTR				__restrict

// declare variable is local variable for thread
// !!! for static linking only
#define UX_THREAD_LOCAL				__declspec( thread )

//
#define UX_NO_RETURN				__declspec( noreturn )

//
#define __CDECL						__cdecl

#if COMPILER_VERSION > 1500
#	define UX_NULL_PTR				nullptr
#endif

//-------------------------------------------------------------------



// C++ 11 features //

// final, constexpr
#if COMPILER_VERSION <= 1600
//	supported: decltype, override
#	define final
#	define constexpr
#	define noexcept							throw()
#endif


// override, decltype
#if COMPILER_VERSION <= 1500
#	define override
#	define decltype(_value)					STATIC_WARNING( "decltype not supported" )
#endif


// variable arguments in macro
#if COMPILER_VERSION > 1500
#	define ARGS(...)						__VA_ARGS__
#	define __UX_EMPTY_ARGS(...)		
#endif


// right value reference
#if ( _MSC_VER >= 1600 )
#	define UX_RVALUE_REFERENCE_SUPPORTED	1
#	define RVALUE_REFERENCE_ONLY			ARGS
#	define WITHOUT_RVALUE_REF_ONLY			__UX_EMPTY_ARGS
#else
#	define RVALUE_REFERENCE_ONLY			__UX_EMPTY_ARGS
#	define WITHOUT_RVALUE_REF_ONLY			ARGS
#endif


// auto
#if ( _MSC_VER >= 1600 )
#	define UX_AUTO_SUPPERTED				1
#else
#	define UX_AUTO_SUPPERTED				0
#	define auto								STATIC_WARNING( "auto not supported" )
#endif


// static assert
#if ( _MSC_VER < 1600 )
#	define  __UX_UNIQUE_STATIC_ASSERT_NAME( a )	a##__LINE__
#	define	static_assert( _b_val, _text )		typedef int	__UX_UNIQUE_STATIC_ASSERT_NAME( __static_assert_ ) [ (_b_val) ? 1 : 0 ]
#endif

//-------------------------------------------------------------------



// Other //

//#define UX_BREAK_POINT()		__asm { int 3 }
#define UX_BREAK_POINT()		__debugbreak()


#ifndef and
#	define and		&&
#endif

#ifndef or
#	define or		||
#endif

#ifndef not
#	define not		!
#endif


// Intrin for MSVC and Windows Platform //
#include "IntrinMSVC.h"


//-------------------------------------------------------------------

#endif	// _UXS_MSVC_COMPILER_H
#endif	// COMPILER_MSVC